﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;

using System.Threading;

using SpotItComponents;
using SpotItServerAPI;

using Vitruvian.Communications.Sockets;
using Vitruvian.Distribution;
using Vitruvian.Serialization;
using Vitruvian.Services;
using Vitruvian.Testing;
using Vitruvian.Logging;

namespace SpotItServerTester
{
    public class BaseTester
    {
        #region Protected Data Members
        protected static bool providerAdded = false;
        protected static int maxWaitingTime = 60000;
        protected static SymbolManager symbolManager = null;
        protected static AccountManager accountManager = null;
        protected static CategoryManager categoryManager = null;
        protected static DeckManager deckManager = null;
        protected static GameManager gameManager = null;
        protected static Session mySession = null;
        #endregion

        protected void EstablishConnectionToServer()
        {
            DistributionService distributionService = ServiceRegistry.GetPreferredService<DistributionService>();

            // If there isn't already a connection to the server, then add one
            if (!providerAdded)
            {
                Console.WriteLine("Be sure the SpotItServer is runnning");
                Console.WriteLine("");
                Console.Write("Enter server IP address and port (default - 127.0.0.1:2345): ");
                string remoteEPstr = Console.ReadLine();
                if (string.IsNullOrEmpty(remoteEPstr))
                    remoteEPstr = "127.0.0.1:2345";

                // Parse the user specific ip address and port
                IPEndPointFormatter ipEndPointFormatter = new IPEndPointFormatter();
                IPEndPoint2 remoteEP = ipEndPointFormatter.Unformat(remoteEPstr) as IPEndPoint2;

                // Create a communication provider (TCP Client) to connect with the server
                TcpClientProvider provider = new TcpClientProvider();
                provider.RemoteEndPoint = remoteEP;

                distributionService.AddProvider(provider);
                providerAdded = true;
            }
        }

        protected void WaitForAllDistributedServices()
        {
            symbolManager = GetDistributedService<SymbolManager>();
            accountManager = GetDistributedService<AccountManager>();
            categoryManager = GetDistributedService<CategoryManager>();
            deckManager = GetDistributedService<DeckManager>();
            gameManager = GetDistributedService<GameManager>();
        }

        protected T GetDistributedService<T>() where T : IService
        {
            T service = default(T);

            int maxTime = maxWaitingTime;
            while ((service = ServiceRegistry.GetPreferredService<T>()) == null && maxTime > 0)
            {
                Thread.Sleep(100);
                maxTime -= 100;
            }
            return service;
        }

        protected void LoginInAsAdmin()
        {
            if (mySession == null)
            {
                System.Console.Write("Admin Username (default - admin): ");
                string username = System.Console.ReadLine();
                if (string.IsNullOrEmpty(username))
                    username = "admin";

                System.Console.Write("Passwword (default - admin): ");
                string password = System.Console.ReadLine();
                if (string.IsNullOrEmpty(password))
                    password = "admin";

                OperationResult result = accountManager.Login(username, password);
                if (result.Success)
                    mySession = result.Data as Session;
            }
        }

    }
}
